package me.project.android_service.listener;

import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import me.project.android_common.domain.SendData;
import me.project.android_common.domain.WebApp;
import me.project.android_service.mapper.WebAppMapper;
import me.project.android_service.service.IAndroidInfoService;
import me.project.android_service.service.IWebAppService;
import me.project.android_service.util.FileUploader;
import me.project.common.exception.BusinessException;
import me.project.common.exception.HttpStatus;
import me.project.android_common.domain.AndroidInfo;
import me.project.android_service.util.MailUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


@Component
@RefreshScope
public class SimpleListener {
    @Resource
    private IAndroidInfoService androidInfoService;

    @Value("${receiver.email}")
    private String receiver;

    @Resource
    private MailUtil mailUtil;

    @Resource
    private IWebAppService webAppService;

    @Value("${rootPath.path}")
    private String rootPath;

    @Value("${serverIp.ip}")
    private String ip;

    @Value("${cloneUrl.address}")
    private String address;

    private void sendEmailToAdmin(int sum) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        String subject = "安卓打包异常提醒";
        String emailTemplate = "sendEmail";
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("createTime", sdf.format(new Date()));
        dataMap.put("name", sum);
        try {
            mailUtil.sendTemplateMail(receiver, subject, emailTemplate, dataMap);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(HttpStatus.SEND_FAIL.getCode(),HttpStatus.SEND_FAIL.getMessage());
        }
    }

    @KafkaListener(topics = "android",groupId = "android")
    public void listen1(List<AndroidInfo> data1, Acknowledgment acknowledge) {
        for (AndroidInfo data : data1) {
            System.out.println("打包完成，返回数据：-->>"+data);
            System.out.println("开始生成二维码以及url");
            try {
                String qr = data.getFullPath()+"/qrcode.jpg";
                String jks = "D:\\apk\\jks\\"+data.getPackageName().trim().toLowerCase(Locale.ROOT).replaceAll("\\.","")+".jks";
                String jksQr = data.getFullPath()+"/jksQr.jpg";
                String jksDownloadUrl = ip + data.getPackageName()+"/"+data.getBuildTime()+"/jksQr.jpg";
                String qrcodeDownloadUrl = ip + data.getPackageName()+"/"+data.getBuildTime()+"/qrcode.jpg";

                QrConfig config = new QrConfig();
                config.setErrorCorrection(ErrorCorrectionLevel.H);

                //jks
                String uploadJks = FileUploader.upload(jks, rootPath + data.getPackageName() + "/" + data.getBuildTime());
                String jksUrl = ip + data.getPackageName()+"/"+data.getBuildTime()+"/"+uploadJks;
                System.out.println(jksUrl);
                File generateJks = QrCodeUtil.generate(jksUrl, /*QrConfig.create().setImg("e:/logo_small.jpg"),*/300,300, FileUtil.file(jksQr));

                //jksQr
                FileUploader.upload(generateJks.getAbsolutePath(), rootPath + data.getPackageName() + "/" + data.getBuildTime());

                //apk
                String uploadApk = FileUploader.upload("D:\\apk\\" + data.getApkPath(), rootPath + data.getPackageName() + "/" + data.getBuildTime());

                String url = ip + data.getPackageName()+"/"+data.getBuildTime()+"/"+uploadApk;
                File generate = QrCodeUtil.generate(url, /*QrConfig.create().setImg("e:/logo_small.jpg"),*/300,300, FileUtil.file(qr));
                //qrcode
                FileUploader.upload(generate.getAbsolutePath(), rootPath + data.getPackageName() + "/" + data.getBuildTime());

                System.out.println("生成 二维码：-->>"+ generate);
                System.out.println("apk路径：-->>"+ data.getApkPath());
                System.out.println("生成 apk下载url：-->>"+ url);
                System.out.println("jks密钥二维码路径：-->>"+ generateJks);
                System.out.println("生成 jks密钥下载url：-->>"+ jksDownloadUrl);
                System.out.println("生成 qr apk二维码下载url：-->>"+ qrcodeDownloadUrl);
                data.setDownloadUrl(url);
                data.setIsPackage(1);
                data.setApkQr(qrcodeDownloadUrl);
                data.setJksQr(jksDownloadUrl);
                System.out.println(data);
                androidInfoService.update(data,new QueryWrapper<AndroidInfo>().eq("uuid",data.getUuid()));
                WebApp webApp = new WebApp();
                webApp.setApk_link(url);
                webAppService.update(webApp,new QueryWrapper<WebApp>().eq("march_code",data.getCode()));
                acknowledge.acknowledge();
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("Re-uploading");
            }
        }
    }
    private final Lock lock = new ReentrantLock();
    private static int failureCount = 0;
    private static final int FAILURE_THRESHOLD = 10;
    @KafkaListener(topics = "android_generate",groupId = "android_generate")
    public void listen2(List<SendData> data1, Acknowledgment acknowledge) {
        for (SendData data : data1) {
            try  {
                String uniqueDirName = "build_" + UUID.randomUUID().toString();
                File workDir = new File("D:\\do\\" + uniqueDirName);
                if (!workDir.exists() && !workDir.mkdirs()) {
                    throw new RuntimeException("Failed to create directory: " + uniqueDirName);
                }

                String cloneCommand = address +" "+ workDir.getAbsolutePath();
                ProcessBuilder builder1 = new ProcessBuilder("cmd", "/c", cloneCommand);
                builder1.redirectOutput(ProcessBuilder.Redirect.INHERIT);
                builder1.redirectError(ProcessBuilder.Redirect.INHERIT);
                Process process1 = builder1.start();
                int exitCode1 = process1.waitFor();
                if (exitCode1 != 0) {
                    throw new RuntimeException("Git clone failed");
                }

                System.out.println("开始查询命令uuid: -->> " + data.getUuid());
                AndroidInfo androidInfo = androidInfoService.getOne(new QueryWrapper<AndroidInfo>().eq("uuid", data.getUuid()));

                System.out.println("查询到: -->> " + androidInfo);
                System.out.println("开始执行生成key的命令: " + androidInfo);
                String path = "D:\\apk\\jks"+"\\"+androidInfo.getPackageName().trim().toLowerCase(Locale.ROOT).replaceAll("\\.","")+".jks";
//            String path = "C:\\Users\\LT02\\Desktop\\apk\\jks"+"\\"+androidInfo.getAppName().trim()+".jks";
                File file = new File(path);

                if (file.exists()) {
                    System.out.println("文件已存在: " + path);
                } else {
                    System.out.println("文件不存在，将创建: " + path);
                    generateKeyStore(path, androidInfo.getPackageName().trim().toLowerCase(Locale.ROOT));
                }
                System.out.println("开始执行打包的命令: userId-->>" + data.getUuid());
                ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "gradlew.bat", "assembleRelease",
                        "-Pandroid.injected.signing.store.file=" + path,
                        "-Pandroid.injected.signing.store.password=" + androidInfo.getPackageName().trim().toLowerCase(Locale.ROOT),
                        "-Pandroid.injected.signing.key.alias=" + androidInfo.getPackageName().trim().toLowerCase(Locale.ROOT),
                        "-Pandroid.injected.signing.key.password=" + androidInfo.getPackageName().trim().toLowerCase(Locale.ROOT),
                        "-PUUID=" + data.getUuid(),
                        "-PUNIQUEDIRNAME=" + uniqueDirName,
                        "-PURL=" + data.getUrl());
//            builder.directory(new File("D:\\software\\Dynamicallyacquired"));
//            builder.directory(new File("C:\\Users\\LT08\\Desktop\\Dynamicallyacquired"));
                builder.directory(workDir);
                builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
                builder.redirectError(ProcessBuilder.Redirect.INHERIT);

                Process process = builder.start();
                int exitCode = process.waitFor();
                System.out.println("Process exited with code: " + exitCode);
                if (exitCode==0){
                    acknowledge.acknowledge();
                }else {
                    failureCount++;
                    if (failureCount >= FAILURE_THRESHOLD) {
                        failureCount = 0;
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                sendEmailToAdmin(failureCount);
                            }
                        }).start();
                    }
                }
                ProcessBuilder builder3 = new ProcessBuilder("cmd", "/c", "rmdir", "/s", "/q", workDir.getAbsolutePath());
                builder3.start().waitFor();
            } catch (Exception e) {
                e.printStackTrace();
//            acknowledge.acknowledge();
                throw new BusinessException("Repacking, please wait!");
            }
        }
    }

    private void generateKeyStore(String keystorePath,String keypass) throws IOException, InterruptedException {
        List<String> command = Arrays.asList(
                "keytool", "-genkeypair", "-v",
                "-keystore", keystorePath,
                "-alias", keypass,
                "-keyalg", "RSA", "-keysize", "2048", "-validity", "10000",
                "-storepass", keypass, "-keypass", keypass,
                "-dname", String.format("CN=%s, OU=%s, O=%s, L=%s, S=%s, C=%s", keypass, keypass, keypass, keypass, keypass, "US")
        );

        ProcessBuilder builder = new ProcessBuilder(command);
        builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
        builder.redirectError(ProcessBuilder.Redirect.INHERIT);
        Process process = builder.start();
        int exitCode = process.waitFor();

        if (exitCode != 0) {
            throw new RuntimeException("Failed to generate keystore");
        }
    }

    @KafkaListener(id = "dltGroup1", topics = "android_generate.DLT")
    public void dltListenSendData(SendData data) {
        System.out.println("Received from DLT: "+data);
    }

    @KafkaListener(id = "dltGroup2", topics = "android.DLT")
    public void dltListen(AndroidInfo data) {
        System.out.println("Received from DLT: "+data);
    }



}
